HeadShot: 基于计算机视觉的自瞄

您所在的位置:网站首页 fps ai辅助 HeadShot: 基于计算机视觉的自瞄

HeadShot: 基于计算机视觉的自瞄

2023-09-11 20:37| 来源: 网络整理| 查看: 265

logo

“Aimbot”

基于计算机视觉的自动瞄准

Platform Version README Contact

Build contribution License

写在前面

只交流技术,勿做其他用途。只交流技术,勿做其他用途。只交流技术,勿做其他用途。

希望每位点开进来的朋友先明白这一点,然后再看下面的文章。

本人是考研途中躺平摸鱼人的一员,所以回复评论以及私信解答等会比较慢,请见谅。

本人FPS游戏不怎么接触,如果下文的相关内容出现错误,请在评论区指正,感恩比心♥

本人不在任何PVP游戏使用非法作弊软件以及脚本(因为我从来不打PVP)

先放个Gridshot Percision的排行榜世界第一实战效果:

外挂技术简述

游戏的外挂从单机时代开始已经有了长足的发展,但一般都可以分为两派:一类是自动化处理,模拟键盘或者鼠标的输入输出,一类是内存修改,进行欺骗性的封包传输。在网络FPS游戏中,大部分采用的是第二种,原因如下:

基于内存的数据容易处理,处理速度快 逆向技术的发展使得该方法积累了大量经验

相比于第二类方法,在要求低延时的FPS游戏中,第一种的应用场景并不看好,原因如下:

动态环境下的目标识别的困难 模拟操作的困难

但它的优势也很明显:不容易被反作弊系统识别。因为:

游戏在运行时只会扫面和自身相关的内存区域有无被非法读写,其余区域不做检查,意味着很难通过内存找到基于CV的目标识别程序的痕迹 鼠标的模拟输入本质是dos指令。在GUI界面还没出现之前,DOS命令承担了所有需要鼠标操作的工作,而鼠标本质上也是通过驱动程序将晶元脉冲信号转换成DOS命令,是被允许的。

本文采用第一种方法实现自动瞄准。

测试环境介绍

测试平台使用Steam的免费射击训练软件Aimlab。该软件集成了如下模块:

单静态目标射击 多静态目标射击 单动态目标射击 多动态目标射击 目标检测射击

前四条基本涵盖了FPS游戏中的会遇到的所有情况,而且Aimlab本身对内存占用不大(我16G的内存开着pycharm跑神经网络和奥日2根本打不开obs录屏),且支持高刷新率的画面。因此作为本次测试的对象。

软件方面,使用pycharm+python3.8。所需库主要有opencv,win32api,辅助分析使用的主要有matplotlib(画图)和numpy,pandas(数据处理)。

硬件方面,CPU是AMD2600x(用于跑程序),内存是2*8G双通道,显卡是七彩虹3070ti Ultra W OC(考虑到现阶段显卡价格的原因,我在这里不使用显卡来跑程序,看看能做到什么程度,仅使用显卡保持144Hz 300帧的游戏画面输出)。

所需解决的问题

键盘、鼠标的模拟输入。

python有pyautogui库可以模拟鼠标键盘输入,但我觉得不太理想。我们可以采用最原生态的方法win32api的接口来完成,效率高速度快。这个可以参考油管大神的视频和他的代码,Github访问受限的朋友可以尝试使用镜像访问或访问文章末尾的🔗链接。这段程序非常经典,可以说是每一个尝试用程序玩游戏的朋友都见过。

画面的截取

python有opencv库,可以截取特定界面的画面。但尝试过opencv库的朋友一定会被它的效率深深担忧,其速度之慢好比我两周都还没看完一章专业课内容。我们还是采用win32api来获取画面。代码依然在文末链接,在Tool的ImageGrab中可以调用。

目标的识别

在这个问题上我要谨慎点说了。现行最快的目标识别算法是YOLO系列,最新的版本是5还是x/r我不太清楚了,有条件的话可以根据自己的需求来训练模型。我不提供任何训练数据集以及训练好的模型,一切都看使用者的想法,本人与此无任何关联。

还记得前面我说的话吗?除了写在前面的那一句,还有一句:

"不使用显卡来跑程序,看看能做到什么程度"

所以针对Aimlab这个游戏(此处的针对是指测试对象的针对,不是针对公司以及开发人员,非常感谢他们推出的这款软件免费让大家训练枪法,如果可以的话希望大家多多支持开发团队),我会采用另一种方法来完成目标检测,同时我也会在后续文给出检测这类作弊的方法。

Coding思路

首先是目标的识别。所谓识别,首先要认出目标,然后还要知道目标的坐标位置。观察我们的射击对象,都为蓝色$^{[1]}$的小球。因此我们可以考虑滤色的方法来实现目标检测。当然你GPU够猛你可以挂目标识别网络去弄这个,如图所示:

训练的模型和训练数据就不给出来了,我只提供思路和方案,具体的实现就留给大家去研究吧。

回到正题上来,如何完成滤色?很多朋友会说RGB选择蓝色通道滤色就好了,确实这是很多人包括我的第一想法。但如果你有Photoshop并把红色和绿色通道关闭后,你会得到这样的效果:

image-20210802224245284

看来效果并不理想,因为我们是希望只保留球的存在而其他物品并不存在。这时候我们要考虑另一种颜色空间——HSV。

HSV的颜色空间讲解可以上网看看,我就不再赘述了。我们要做的一件事就是滤色,就像设计带通滤波器一样,确定频率上下限,这个不难吧!确定上下限后,就相当于设计了一个遮罩,只有这个范围内的颜色会被通过,其余颜色会被阻挡,即置零。在HSV中,[0,0,0]代表的就是黑色,这点倒是和RGB很像。

所以接下来要处理颜色的滤色上下限问题。

颜色上下限的确定

我们先将HSV输出的图像保存。然后我们观察我们的蓝色球体的HSV取值范围,将其作为上下限。我们使用opencv来处理RGB到HSV的颜色空间转换,同时设计鼠标点击事件,使鼠标点击图片时返回该点的HSV值。~~代码在getColor中有定义。~~我已修改了更优的阈值数组。

再看修改结果:

已经比较完美(?)了,滤色,或者说目标识别部分完成!

目标定位

首先先确定准星坐标。我们知道FPS游戏的准星一般位于屏幕中央,因此,它对应的坐标为分别率的二分之一。例如分辨率为1920x1080的显示器,对应的准星坐标为(960,540)。这里有一个坑,也可能只有我才会有:我的屏幕是创维的伪2K带鱼屏,分辨率是2560x1080,但在游戏中如果以全屏进行游戏的话,抓取屏幕的分辨率其实是3240*1440,这点要注意。

其次是设计目标的定位,这个也好办。同样也是使用opencv中的画矩形把识别到的颜色给框起来,返回参数为x,y,w,h,分别对应矩形的横坐标纵坐标起点以及长宽。这样我们的目标中心坐标就可以写为: $$ x_{target}=x+\frac{1}{2}w\\ y_{target}=y+\frac{1}{2}h $$ 在调试的时候我们可以print一下结果看看大致情况。

鼠标射击事件

我们打开Aimlab的Detection训练,用来测试程序的反应灵敏性。该训练模式要求很简单:

当且仅当屏幕出现蓝色球体时按下鼠标,从出现到按下的时间越短,分数越高 未出现蓝色球体目标时不能按下鼠标,否则扣分

规则非常简单,我们如何做到识别物体检测呢?其实可以判断目标检测中矩形框的返回参数w或h的大小判断。若其中一个值大于0则可认为目标出现。如果担心有问题的话,可以通过其他手段比如四个参数之和小于某个数等等等等作为threshold,以防出现误判情况。

~~鼠标按键事件由按下与松开两个部分组成,代码在getkeys中有定义。~~现已改为直接调用win32api了。

鼠标移动事件

FPS游戏中鼠标有2*2个移动方向,分别是上下左右,因此,我们可以设置参数或者直接复制粘贴四个函数让你的代码看起来更多一点。

这里的参数size代表了移动的幅度,越大移动幅度越大。下面就是逻辑判断环节:如果准星坐标和目标中心坐标相减小于零则说明靠左靠下,大于零则说明靠右靠上。写个If判断即可,至于移动方式,可以选择共同步进,也可以选择先横后竖步进,执行起来在高速情况下是差不多的。我这里选用的是同步步进。

win32api的鼠标事件自行设置,效率会更高(更像机器,自行取舍)。

上手测试!

把该有的补全,开用!在主程序中设定号调用的function即可使用。

修改以及进阶空间

就像我之前说了,想要做到文章开头的那个效果,或者比那个效果更好、更全面其实还有很多进步空间。我给出的代码非常简单,也留有非常多可以改进的地方,包括但不限于有如下几个方面。把代码分享出来的目的就是希望大家能完善这个代码或者这一套算法,这样我也会很开心的。下面我给出我暂时想到的问题还有一些解决方案:

移动坐标的映射问题

细心调试过的朋友应该也发现了,鼠标移动的距离按理来说应该是匀速的,但通过测试发现并非满足匀速的关系。我对size取3,10,20等情况,对移动距离进行采样和分析,做出如下图象(有两张丢了但我也懒得弄了。。大概是这样子的:

size5

可以发现随着函数匀速执行,移动距离呈二次函数关系(看的是趋势,有些异常点是我碰了鼠标的原因,size10后半截是没喊停采样导致的误差),其实是可以做出解释的。在一个三维空间的FPS游戏,移动鼠标其实是以玩家为圆心以移动鼠标的速度作为角速度进行移动。将三维图像通过畸变映射到渲染图像的过程中,移动的距离发生了畸变,畸变的结果就是在两端的移动距离会变大,在中间的时候移动的距离会变小。

画图解释一下就是这样(字丑将就看吧:

img 解决方法

最靠谱的方法是采集数据然后做拟合,这个是可行的。

最不靠谱的方法就是我的解决方案:依旧是逻辑判断,但是要通过更高一层的逻辑判断,即获取此时视角来判断移动范围进而确定移动范围。

最佳寻址的操作

如果不考虑上面的问题,我们把问题简化一下:给定若干(n个)幅度的鼠标移动操作,然后分别执行对这些操作执行若干次,使得执行结果为准星对准到目标中心或者运行范围。满足此条件下,寻找执行操作数之和的最小值。用高大上一点的语言就是: $$ A=[a_1,a_2,...,a_n], {\exists} B=[b_1,b_2,...,b_n],B=\arg \min{,}\sum_{i=1}^{n}b_i,{,}s.t. {,}{,}{,}{,}AB^T=const.\\ or\\ A=[a_1,a_2,...,a_n], {\exists} B=[b_1,b_2,...,b_n],B=\arg \min{,}\sum_{i=1}^{n}b_i,{,}s.t. {,}{,}{,}{,}|AB^T-const| \leq\epsilon\\ $$

$a_i$为不同幅度的鼠标操作 $b_i$为不同幅度的操作数 $const$为准星与目标中心距离 $\epsilon$为允许准星偏移的误差 解决方法

拉格朗日乘子法。我在设定size分别取3,5,15时可以得到一个不错的解,证明是可行的,效果就如开头所示。余下的交给各位去探索研究了,期待大家的Pull。

顺提一嘴,scipy这个库有比较好的实现方法。

静态目标的寻址方法

高大上点的叫法是伪梯度逼近法,实际上就是普通的相减逼近,原理就是移动的像素与游戏世界中的移动在足够小的情况下是近似相等的,但这并不意味着上文未删除的部分没有研究价值,因为使用这种方法是永远不可能完成动态目标的追踪任务(效率不高)。

*目标追踪

看到这里的话我相信如果你动手操作过前面的代码并理解后,肯定能想到。

如果实在想不到我给一个思路:

目标的运动是有持续时间 目标的运动近似认为是匀速运动 一定时间差会导致准星跟不上移动的目标,但准星能跟着目标移动过的轨迹走

本质上是卡尔曼滤波器,或者使用PID控制中的积分控制保持。

破壁or被破壁

其实抓取目标出现以及确认点击的时间即可很好分辨作弊与否。不同寻路的方式归根到底都可以被量化,一些特定位置的目标的响应时间其实能很好判断是否利用了程序计算。突破点是相对坐标而非绝对坐标,可以从图像的抽帧、编码的角度来思考这个问题,但这个太费脑子了...

另外,监督学习除了让机器学会人的操作的同时,能不能让机器去评价人的操作?图片的叠加和滤波能告诉我们什么信息?思路就到这了 摸了



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3